import { getFunctionArgsName } from './common'
import mysql, { PoolConfig } from 'mysql'
import { FunctionAnnotation } from './decoratorType'

var pool: mysql.Pool

const resultTypeMap = new Map<string, object>()

export const load = (mysqlConfig: PoolConfig): any => {
  pool = mysql.createPool(mysqlConfig)
  // 第一回合查询是否能链接成功,用于报错用户名密码错误
  pool.getConnection(function (err) {
    if (err) {
      console.log(err)
      return
    }
  })
}

var db: any = {}

db.query = function (sql: string) {
  return new Promise((resolve, reject) => {
    pool.getConnection(function (err, connection) {
      if (err) {
        reject(err)
        return
      }

      connection.query(sql, function (error, results) {
        connection.release()
        if (error) {
          reject(error)
          return
        }
        resolve(results)
      })
    })
  })
}

export function ResultType(constructorFunction: any): FunctionAnnotation {
  return function (target, propertyKey, descriptor: PropertyDescriptor) {
    process.nextTick(() => {
      resultTypeMap.set([target.constructor.name, propertyKey].toString(), new constructorFunction())
    })
  }
}

// 应该反过来，从sql上进行遍历，sql变量能一次修改多次复用
export const Sql = function (sql: string): FunctionAnnotation {
  return function (target, propertyKey, descriptor: PropertyDescriptor) {
    let targetName = target.constructor.name.toString()
    process.nextTick(() => {
      target[propertyKey] = new Proxy(target[propertyKey], {
        apply: async (target, thisBinding, args) => {
          let currentSql = sql
 
          if (typeof args[0] === 'object') {
            for (let i in args[0]) {
              const spliceReg = new RegExp(`#{+\s*${i}+\s*}`, 'g')
              const evalReg = new RegExp('\\' + `\${+\s*${i}+\s*}`, 'g')

              if (spliceReg.test(currentSql)) {
                currentSql = currentSql.replace(spliceReg, `'${args[0][i]}'`)
              } else if (evalReg.test(currentSql)) {
                currentSql = currentSql.replace(evalReg, `${args[0][i]}`)
              }
            }
          } else {
            if (getFunctionArgsName(target.toString())[0] !== '') {
              getFunctionArgsName(target.toString())?.map((item, index) => {
                const spliceReg = new RegExp(`#{+\s*${item}+\s*}`, 'g')
                const evalReg = new RegExp('\\' + `\${+\s*${item}+\s*}`, 'g')

                if (spliceReg.test(currentSql)) {
                  currentSql = currentSql.replace(spliceReg, `'${args[index]}'`)
                } else if (evalReg.test(currentSql)) {
                  currentSql = currentSql.replace(evalReg, `${args[index]}`)
                }
              })
            }
          }

          // 这里想办法让他不解析，在启动时就拼接好
          console.log(`sql查询${currentSql}`)

          const rows = await db.query(currentSql)
          const resultType = resultTypeMap.get([targetName, propertyKey].toString())

          let records = []

          if (resultType !== undefined) {
            for (const rowIndex in rows) {
              const entity = Object.create(resultType)
              Object.getOwnPropertyNames(resultType).forEach(function (propertyRow) {
                if (rows[rowIndex].hasOwnProperty(propertyRow)) {
                  Object.defineProperty(entity, propertyRow, Object.getOwnPropertyDescriptor(rows[rowIndex], propertyRow) as PropertyDescriptor)
                }
              })
              records.push(entity)
            }
          } else {
            records = rows
          }

          return records
        },
      })
    })
  }
}

export const query = <T>(sql: string): T => {
  return db.query(sql)
}
